import { Tsrv } from '@/services';
import Vue from 'vue';
import { i18n } from './i18n.config';

interface I_msg {
  code: string;
  from: string;
  level: number;
  vals: Array<string>;
  info: string;
  content: string; // 提示内容
  type: string; // 消息类型
}
const remindCode = '-50014';

// 检查消息表达式
const chkMsgExpr = (msgArr: Array<string>): boolean => {
  // 消息代码 , 消息来源, 消息等级 , [变量] , [补充信息]
  // 变量 *xxx~|~xxx#
  const sLen: number = msgArr.length;
  return sLen < 3 || sLen > 5;
};
// 解析变量
// 如果第四段可以是变量，也可以是补充信息
const getVals = (msgArr: Array<string>): Array<string> => {
  if (msgArr.length < 4) {
    return [];
  }
  const vS: string = msgArr[3].trim();
  const arr = [];
  //* xxxxx#
  if (/^\*.*#$/.test(vS)) {
    return vS.substring(1, vS.length - 1).split('~|~'); // ~|~ 分隔符
  }
  // [xxxxx]
  if (/\[(.*?)\]$/g.test(vS)) {
    // Invalid parameter[mode=strict|match]
    // const arr = [];
    arr.push(Tsrv.getI18nBySrv(/\[(.*?)\]$/g.exec(vS)[1]));
    // return arr;
  }
  // {xxxxx}
  if (/{([^}]+)}/g.test(vS)) {
    // Undefined type{0}!
    // const arr = [];
    arr.push(Tsrv.getI18nBySrv(/{([^}]+)}/g.exec(vS)[1]));
    // return arr;
  }

  return arr;
};
// 获取补充信息
const getInfo = (msgArr: Array<string>): string => {
  const sLen: number = msgArr.length;
  if (sLen < 4) {
    return '';
  }

  if (sLen === 4) {
    // 这段如果是变量表示则返回空
    //* xxxxx#
    if (/^\*.*#$/.test(msgArr[3].trim())) {
      return '';
    }
    return msgArr[3];
  }
  if (sLen === 5) {
    return msgArr[4];
  }
  return '';
};
const msgHandle = (msgStr: string, ...val: string[]): I_msg => {
  // 分隔arr
  const arr: Array<string> = msgStr.split(',');
  let vs = [];
  if (val.length > 0) {
    vs = val;
  } else {
    vs = getVals(arr);
  }
  const msg: I_msg = {
    // 获取消息代码，来源，等级，变量 ，额外信息
    // code: parseInt(arr[0], 10),
    code: arr[0],
    from: arr[1],
    level: parseInt(arr[2], 10),
    vals: vs,
    info: getInfo(vs),
    content: '',
    type: ''
  };

  // 定义提示的内容和类型
  if (msg.code === '0' || !i18n.te(`msg.${msg.code}`)) {
    // code为0时，用来源+额外信息显示，类型为错误，（来自前端的错误，XXXXX）
    // const i18nMsg =
    //   msg.vals.length > 0
    //     ? i18n.t(`msg.${msg.from}`, msg.vals)
    //     : i18n.t(`msg.${msg.from}`);
    // msg.content = i18nMsg + msg.info;
    msg.content = `${i18n.t(`msg.${remindCode}`).toString()}-${msgStr}`;
    msg.type = 'error';
  } else {
    // code不为0时，显示代码信息
    // msg.content =
    //   msg.vals.length > 0
    //     ? i18n.t(`msg.${msg.code}`, msg.vals).toString()
    //     : i18n.t(`msg.${msg.code}`).toString();
    const codeStr = i18n.t(`msg.${msg.code}`).toString();
    const placeholderCount = (codeStr.match(/\{\d+\}/g) || []).length;
    const valsLen = msg.vals.length;
    if (valsLen > 0) {
      if (valsLen < placeholderCount) {
        const vals = [...msg.vals];
        const diff = placeholderCount - valsLen;
        for (let i = 0; i < diff; i++) {
          vals.push('???');
        }
        msg.content = i18n.t(`msg.${msg.code}`, vals).toString();
      } else if (valsLen > placeholderCount) {
        const content = i18n.t(`msg.${msg.code}`, msg.vals).toString();
        const vsRest = [...msg.vals].slice(placeholderCount);
        msg.content = `${content}，${Tsrv.getI18nBySrv(
          'message_variable'
        )}[${vsRest.join('，')}]`;
      } else {
        msg.content = i18n.t(`msg.${msg.code}`, msg.vals).toString();
      }
    } else {
      msg.content = codeStr.replace(/\{(\d+)\}/g, '???');
    }
    if (/^[1-9]\d/.test(msg.code)) {
      // 当code > 0 时，level = 0 则为成功，不为0时则为通知
      msg.type = msg.level === 0 ? 'success' : 'info';
    } else {
      // 当code < 0 时，level < 80 则为警告，大于80则为错误
      // msg.type = msg.level < 80 ? 'warning' : 'error';
      msg.type = 'error';
    }
  }
  return msg;
};
const defaultShowMsg = (msg: string) => {
  // 默认情况直接显示错误
  Vue.prototype.$Message.error({
    content: msg,
    background: true,
    closable: true,
    duration: 8 // 延时时间
  });
};
const addErrDetail = (title: string, content: string) => {
  Tsrv.TerrDet.add({ title, content });
  Tsrv.reliablySendingBusEvent('chgErrListFunc');
};
const showMsg = (msgStr: string, ...vals: string[]) => {
  const m: I_msg = msgHandle(msgStr, ...vals);
  // 提示时间
  let durationTime: number;
  switch (m.type) {
    case 'success':
      durationTime = 3;
      break;
    case 'warning':
      durationTime = 5;
      break;
    case 'error':
      durationTime = 8;
      addErrDetail('错误', msgStr);
      break;
    default:
      durationTime = 3;
  }
  const content = m.content;
  // 放出消息
  Vue.prototype.$Message[m.type]({
    content,
    background: true,
    duration: durationTime, // 延时时间
    closable: true
  });
};

export const msg = (s: any /* string|object */, ...vals: string[]): void => {
  if (!s) {
    return;
  }
  if (typeof s !== 'string') {
    console.error(s);
    addErrDetail(Tsrv.getI18nByValue('错误'), s.toString());

    s = '-50006,FE,90'; // 发生错误,错误内容详见控制台
  }
  if (s.indexOf(',') === -1) {
    addErrDetail(Tsrv.getI18nByValue('错误'), s.toString());
    defaultShowMsg(s);
    return;
  }
  // 当信息字符串存在逗号分隔符
  // 分隔arr
  const arr: Array<string> = s.split(',');
  if (chkMsgExpr(arr)) {
    // 若分隔长度小于3，或消息代码为0，或消息等级为0，则显示为前端报错，整体作为补充信息
    // s = `0,FE,0,${s.replace(/,/, `,`)}`;
    console.error(s);
    addErrDetail(Tsrv.getI18nByValue('错误'), s.toString());
    s = '-50006,FE,90'; // 发生错误,错误内容详见控制台
  }
  const vs = Tsrv.customMsgHandle(s, ...vals);
  showMsg(s, ...vs);
};

Vue.prototype.$msg = msg; // 提示信息
